/**
 * 51. N 皇后
 * 
 * n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上，并且使皇后彼此之间不能相互攻击。
 * 给你一个整数 n ，返回所有不同的 n 皇后问题 的解决方案。
 * 每一种解法包含一个不同的 n 皇后问题 的棋子放置方案，该方案中 'Q' 和 '.' 分别代表了皇后和空位。
 * 
 * 示例 1：
 * 输入：n = 4
 * 输出：[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
 * 解释：如图T51所示，4 皇后问题存在两个不同的解法。
 * 
 * 示例 2：
 * 输入：n = 1
 * 输出：[["Q"]]
 * 
 * 提示：
 * 1 <= n <= 9
 * 皇后彼此不能相互攻击，也就是说：任何两个皇后都不能处于同一条横行、纵行或斜线上。
 * 
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/n-queens
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 * 
 */

package zw;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class T51 {
	public List<List<String>> solveNQueens(int n) {
		List<List<String>> ans = new ArrayList<List<String>>();
		char[][] nQueens = new char[n][n];
        for (int i = 0; i < n; i++) {
            Arrays.fill(nQueens[i], '.');
        }
		boolean[] cUsed = new boolean[n];
		boolean[] lbUsed = new boolean[n*2-1];
		boolean[] rbUsed = new boolean[n*2-1];
		dfs(0, n, nQueens, cUsed, lbUsed, rbUsed, ans);
		return ans;
    }
	
	void dfs(int row, int n, char[][] nQueues, boolean[] cUsed, boolean[] lbUsed, boolean[] rbUsed, List<List<String>> ans){
		if(row == n) {
			ArrayList<String> list = new ArrayList<String>();
			for (char[] chars : nQueues) {
                list.add(new String(chars));
            }
			ans.add(list);
		} else {
			for(int col = 0; col < n; col++) {
				int lb = row + col;
				int rb = n-1-row+col;
				if(cUsed[col] || lbUsed[lb] || rbUsed[rb]) {
					continue;
				}
				cUsed[col] = lbUsed[lb] = rbUsed[rb] = true;
				nQueues[row][col] = 'Q';
				dfs(row+1, n, nQueues, cUsed, lbUsed, rbUsed, ans);
				nQueues[row][col] = '.';
				cUsed[col] = lbUsed[lb] = rbUsed[rb] = false;
			}
		}
	}
	
	public static void main(String[] args) {
		T51 t51 = new T51();
		System.out.println(t51.solveNQueens(6));
	}
}
